/*******************************************************************************
 * Copyright (c) 2006 CEA List.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     CEA List - initial API and implementation
 *******************************************************************************/
package com.cea.papyrus.core.commands.connection;

import org.eclipse.draw2d.geometry.Point;
import org.eclipse.gef.commands.Command;
import org.eclipse.uml2.uml.Element;

import com.cea.papyrus.diagraminterchange2.di2.GraphConnector;
import com.cea.papyrus.diagraminterchange2.di2.GraphEdge;
import com.cea.papyrus.diagraminterchange2.di2.GraphElement;
import com.cea.papyrus.diagraminterchange2.di2.Uml1SemanticModelBridge;


/**
 * Base class for  Command acting on Connections.
 * Provide utility methods.
 * 
 * @author dumoulin
 */
public abstract class ConnectionCommandBase extends Command {

	/**
	 * 
	 */
	public static final int SOURCE = 0;
	
	/**
	 * 
	 */
	public static final int TARGET = 1;


	/**
	 * Constructor.
	 */
	public ConnectionCommandBase() {
		super();
	}

	/**
	 * Get the associated model element from the specified GraphElement.
	 * 
	 * @param element 
	 * 
	 * @return 
	 */
	protected Element getBussinessElementFromGraphElement(GraphElement element) {
		if (element.getSemanticModel() != null) {
			return ((Uml1SemanticModelBridge) element.getSemanticModel()).getElement();
		} else {
			// Purely graphical element
			return null;
		}
	}

	/**
	 * Set the associated model element from the specified GraphElement.
	 * 
	 * @param element 
	 * @param value 
	 */
	protected void setBussinessElementFromGraphElement(GraphElement element, Element value) {
		((Uml1SemanticModelBridge)element.getSemanticModel()).setElement(value);
	}

	/**
	 * Return the anchor at the specified end (SOURCE or TARGET) of the edge.
	 * 
	 * @param edge 
	 * @param end 
	 * 
	 * @return 
	 */
	protected GraphConnector getEdgeAnchor(GraphEdge edge, int end)
	{
		assert(end==SOURCE || end == TARGET);
		return ((GraphConnector)edge.getAnchor().get(end));
	}


	/**
	 * 
	 * 
	 * @param edge 
	 * 
	 * @return The target anchor of the specified edge.
	 */
	protected GraphConnector getTargetAnchor(GraphEdge edge) {
		return ((GraphConnector)edge.getAnchor().get(TARGET));
	}

	/**
	 * 
	 * 
	 * @param edge 
	 * 
	 * @return The source anchor of the specified edge.
	 */
	protected GraphConnector getSourceAnchor(GraphEdge edge) {
		return ((GraphConnector)edge.getAnchor().get(SOURCE));
	}

	
	/**
	 * Get the source GraphElement of the specified Edge.
	 * 
	 * @param edge 
	 * 
	 * @return 
	 */
	protected GraphElement getSource(GraphEdge  edge) {
		return getSourceAnchor(edge).getGraphElement();
	}

	/**
	 * Get the target GraphElement of the specified Edge.
	 * 
	 * @param edge 
	 * 
	 * @return 
	 */
	protected GraphElement getTarget(GraphEdge  edge) {
		return getTargetAnchor(edge).getGraphElement();
	}

	/**
	 * Reconnect the specified graphEdge to its endpoints and its owner. Do nothing with the bussiness model.
	 * 
	 * @param edge 
	 * @param owner 
	 * @param target 
	 * @param source 
	 */
	protected void reconnectGraphEdgeAnchors( GraphEdge edge, GraphElement owner, GraphElement source, GraphElement target )
	{
		getSourceAnchor(edge).setGraphElement(source);
		getTargetAnchor(edge).setGraphElement(target);
		edge.setContainer(owner);
	}

	/**
	 * Disconnect the specified graphEdge from its endpoints and its owner. Do nothing with the bussiness model.
	 * 
	 * @param edge 
	 */
	protected void disconnectGraphEdgeAnchors( GraphEdge edge )
	{
		getSourceAnchor(edge).setGraphElement(null);
		getTargetAnchor(edge).setGraphElement(null);
		edge.setContainer(null);
	}

	/**
	 * Disconnect the specified anchor from its graphElement.
	 * 
	 * @param anchor 
	 */
	protected void disconnectAnchor(GraphConnector anchor)
	{
		anchor.setGraphElement(null);
	}
	
	/**
	 * Recconnect the specified anchor to its graphElement.
	 * 
	 * @param endpoint 
	 * @param anchor 
	 */
	protected void reconnectAnchor(GraphConnector anchor, GraphElement endpoint)
	{
		anchor.setGraphElement(endpoint);
	}
	
	/**
	 * Recconnect the specified anchor to its graphElement.
	 * 
	 * @param endpoint 
	 * @param location 
	 * @param anchor 
	 */
	protected void reconnectAnchor(GraphConnector anchor, GraphElement endpoint, Point location)
	{
		anchor.setGraphElement(endpoint);
		anchor.setPosition(location);
	}
	
}